#include <cmath>

#include "light.h"

double DirectionalLight::distanceAttenuation( const vec3f& P ) const
{
	// distance to light is infinite, so f(di) goes to 0.  Return 1.
	return 1.0;
}


vec3f DirectionalLight::shadowAttenuation( const vec3f& P ) const
{
    // YOUR CODE HERE:
    // You should implement shadow-handling code here.

	// shine the light from the POINT P in the OPPOSITE direction of the directional light, as long as there is an intersect, GG
	ray r(P, this->getDirection(P));
	isect i;

	if (scene->intersect(r, i)) {
		const Material& m = i.getMaterial();
		if (m.kt * m.kt != 0 )
			return m.kt;
		else
			return vec3f(0, 0, 0);
	}

    return vec3f(1,1,1);
}

vec3f DirectionalLight::getColor( const vec3f& P ) const
{
	// Color doesn't depend on P 
	return color;
}

vec3f DirectionalLight::getDirection( const vec3f& P ) const
{
	return -orientation;
}

double PointLight::distanceAttenuation( const vec3f& P ) const
{
	// YOUR CODE HERE

	// You'll need to modify this method to attenuate the intensity 
	// of the light based on the distance between the source and the 
	// point P.  For now, I assume no attenuation and just return 1.0

	float distance = (position - P).length();
	float distance2 = (position - P).length_squared();
	
	return 1.0f;

	return min(1.0f, 1/(_quadratic_attenuation_coeff * distance2 + _linear_attenuation_coeff * distance + _constant_attenuation_coeff));

}

vec3f PointLight::getColor( const vec3f& P ) const
{
	// Color doesn't depend on P 
	return color;
}

vec3f PointLight::getDirection( const vec3f& P ) const
{
	return (position - P).normalize();
}


vec3f PointLight::shadowAttenuation(const vec3f& P) const
{
    // YOUR CODE HERE:
    // You should implement shadow-handling code here.

	isect i;
	ray r(P, getDirection(P));
	
	if (scene->intersect(r, i)) {
		if (i.t > 0) {
			const Material& m = i.getMaterial();
			
			if (m.kt * m.kt != 0 )
				return vec3f(1,1,1) - m.kt;
			else
				return vec3f(0, 0, 0);
		}

	}

	// No attenuation

    return vec3f(1,1,1);
}
